<?php
declare (strict_types=1);
// +----------------------------------------------------------------------
// | 吸粉红包
// +----------------------------------------------------------------------

namespace app\mall\controller;

use app\BaseController;
use app\mall\model\Bonus;
use app\mall\model\UserBonus;
use think\exception\ValidateException;

class BonusController extends BaseController
{
    /**
     * @OA\Get(path="/bonus",tags={"红包"},summary="列表",
     *   @OA\Parameter(name="authorization", in="header", description="Bearer token", @OA\Schema(type="string")),
     *   @OA\Parameter(name="page", in="query", description="页码", @OA\Schema(type="int", default="1")),
     *   @OA\Parameter(name="limit", in="query", description="行数", @OA\Schema(type="int", default="10")),
     *   @OA\Parameter(name="type", in="query", description="类型", @OA\Schema(type="int", default="10")),
     *   @OA\Response(response="200", description="successful operation")
     * )
     */
    public function index()
    {
        $param = $this->request->param();
        $field = $param['field'] ?? 'id';
        $order = $param['order'] ?? 'desc';
        $limit = $param['limit'] ?? 10;

        $where= [];
        if (isset($param['keyword'])) {
            $where[] = ['name', 'like', '%' . $param['keyword'] . '%'];
        }
        if (isset($param['type'])) {
            $where[] = ['type', '=', $param['type']];
        }
        if (isset($param['status'])) {
            $where[] = ['status', '=', $param['status']];
        }

        $list  = Bonus::where($where)
            ->order($field, $order)
            ->paginate($limit);
        $count = $list->total();
        $list  = $list->items();
        $this->success('获取成功', compact('list', 'count'));
    }

    /**
     * @OA\Post(path="/bonus",tags={"红包"},summary="新增",
     *   @OA\Parameter(name="authorization", in="header", description="Bearer token", @OA\Schema(type="string")),
     *   @OA\RequestBody(
     *     @OA\MediaType(mediaType="multipart/form-data",
     *         @OA\Schema(
     *           @OA\Property(description="红包类型:1活动红包 2关注红包 3奖品红包", property="type", type="integer"),
     *           @OA\Property(description="红包名称", property="name", type="string"),
     *           @OA\Property(description="红包祝福语", property="blessing", type="string"),
     *           @OA\Property(description="红包总面额", property="total_price", type="number"),
     *           @OA\Property(description="是否固定金额", property="price_type", type="integer"),
     *           @OA\Property(description="固定金额", property="fixed_price", type="number"),
     *           @OA\Property(description="随机最小金额", property="price_start", type="number"),
     *           @OA\Property(description="随机最大金额", property="price_end", type="number"),
     *           @OA\Property(description="开始时间", property="start_time", type="string"),
     *           @OA\Property(description="结束时间", property="end_time", type="string"),
     *           @OA\Property(description="红包备注", property="remark", type="string"),
     *           required={"type","name","total_price","price_type","start_time","end_time"})
     *       )
     *     ),
     *   @OA\Response(response="200", description="successful operation")
     * )
     */
    public function save()
    {
        $param            = $this->request->param();
        $param['status']  = 1;
        $this->validate($param, 'app\mall\validate\Bonus');
        $data = Bonus::create($param);
        if (!$data) {
            throw new ValidateException("保存失败");
        }

        // 红包领取记录
        $list = [];
        if ($param['price_type'] == 1) {
            // 固定金额
            if ($param['fixed_price'] == 0 || $param['fixed_price'] > $param['total_price']) {
                $this->error('固定金额或红包总面额错误');
            }
            if (($param['total_price']*100) % ($param['fixed_price']*100) != 0) {
                $this->error('总金额必须是固定金额的整数倍');
            }

            for ($i = 0; $i < $param['total_price'] / $param['fixed_price']; $i++) {
                $list[] = [
                    'bonus_id' => $data->id,
                    'receive_price' => $param['fixed_price']
                ];
            }
        } else {
            // 随机金额
            if ($param['price_start'] == 0 || $param['price_start'] > $param['total_price'] || $param['price_end'] > $param['total_price'] || $param['price_start'] >= $param['price_end']) {
                $this->error('随机金额错误');
            }

            $surplus_price = $param['total_price']; //剩余未计算金额
            while (true) {
                if ($surplus_price <= $param['price_end']) {
                    $receive_price = $surplus_price;
                } else {
                    $receive_price = rand($param['price_start'] * 100, $param['price_end'] * 100) / 100;
                }
                $surplus_price -= $receive_price;
                $list[] = [
                    'bonus_id' => $data->id,
                    'receive_price' => $receive_price
                ];
                if ($surplus_price == 0) {
                    break;
                }
            }
        }

        $user = new UserBonus;
        $res = $user->saveAll($list);
        if (!$res) {
            throw new ValidateException("红包记录生成失败");
        }
        $this->success('保存成功', $data);
    }

    /**
     * @OA\Get(path="/bonus/{id}",tags={"红包"},summary="详情",
     *   @OA\Parameter(name="authorization", in="header", description="Bearer token", @OA\Schema(type="string")),
     *   @OA\Parameter(name="id", in="path", description="id", @OA\Schema(type="int")),
     *   @OA\Response(response="200", description="successful operation")
     * )
     */
    public function read($id)
    {
        $data = Bonus::find($id);
        $this->success('获取成功', $data);
    }

    /**
     * @OA\Put(path="/bonus/{id}",tags={"红包"},summary="编辑",
     *   @OA\Parameter(name="authorization", in="header", description="Bearer token", @OA\Schema(type="string")),
     *   @OA\Parameter(name="id", in="path", description="id", @OA\Schema(type="int")),
     *   @OA\RequestBody(
     *     @OA\MediaType(mediaType="multipart/form-data",
     *         @OA\Schema(
     *           @OA\Property(description="红包类型:1活动红包 2关注红包 3奖品红包", property="type", type="integer"),
     *           @OA\Property(description="红包名称", property="name", type="string"),
     *           @OA\Property(description="红包祝福语", property="blessing", type="string"),
     *           @OA\Property(description="开始时间", property="start_time", type="string"),
     *           @OA\Property(description="结束时间", property="end_time", type="string"),
     *           @OA\Property(description="红包备注", property="remark", type="string"),
     *           required={"type","name","total_price","start_time","end_time"})
     *       )
     *     ),
     *   @OA\Response(response="200", description="successful operation")
     * )
     */
    public function update($id)
    {
        $param = $this->request->param();
        $param['id'] = $id;
        $this->validate($param, 'app\mall\validate\Bonus');
        $data = Bonus::update($param);
        if (!$data) {
            throw new ValidateException("保存失败");
        }
        $this->success('保存成功', $data);
    }

    /**
     * @OA\Delete(path="/bonus/{id}",tags={"红包"},summary="删除",
     *   @OA\Parameter(name="authorization", in="header", description="Bearer token", @OA\Schema(type="string")),
     *   @OA\Parameter(name="id", in="path", description="id", @OA\Schema(type="int")),
     *   @OA\Response(response="200", description="successful operation")
     * )
     */
    public function delete($id)
    {
        // 验证有无使用
        $res = Bonus::destroy($id);
        if (!$res) {
            $this->error("删除失败");
        }
        $this->success('删除成功');
    }

    /**
     * @OA\Put(path="/bonus/{id}/status",tags={"红包"},summary="审核",
     *   @OA\Parameter(name="authorization", in="header", description="Bearer token", @OA\Schema(type="string")),
     *   @OA\Parameter(name="id", in="path", description="id", @OA\Schema(type="int")),
     *   @OA\RequestBody(
     *     @OA\MediaType(mediaType="multipart/form-data",
     *         @OA\Schema(
     *           @OA\Property(description="状态", property="status", type="integer"),
     *           @OA\Property(description="备注", property="admin_note", type="varchar"),
     *           required={"status"})
     *       )
     *     ),
     *   @OA\Response(response="200", description="successful operation")
     * )
     */
    public function status($id)
    {
        $put                 = $this->request->param();
        $param['id']         = $id;
        $param['admin_user'] = $this->user_id;
        $param['admin_note'] = $put['admin_note'] ?? '';
        $param['status']     = $put['status'];
        $data                = Bonus::update($param);
        if (!$data) {
            $this->error("保存失败");
        }
        $this->success('保存成功', $data);
    }
}